#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <wait.h>
int main()
{
  if (access("./pipeline_file1", F_OK) < 0)
  {
    mkfifo("./pipeline_file1", 0644);
  }
  if (access("./pipeline_file2", F_OK) < 0)
  {
    mkfifo("./pipeline_file2", 0644);
  }
  int fds[2];
  if (pipe(fds) < 0)
  {
    perror("管道创建失败");
    exit(-1);
  }
  // 并设置管道为非阻塞读写
  fcntl(fds[0], F_SETFL, O_NONBLOCK);
  fcntl(fds[1], F_SETFL, O_NONBLOCK);

  int pid = fork();
  if (pid > 0) // 父进程
  {
    int fd = open("./pipeline_file2", O_WRONLY);
    if (fd < 0)
    {
      perror("管道文件打开失败");
      exit(-1);
    }
    fcntl(fd, F_SETFL, O_NONBLOCK);

    char buf[1024];
    while (1)
    {
      read(fds[0], buf, sizeof(buf));
      if (strstr(buf, "end") != NULL)
      {
        sleep(1);
        close(fd); // 关闭管道
        exit(0);
      }

      int count = read(0, buf, sizeof(buf)); // 从标准输入读数据,并写到管道
      // write(fd, "tom:", 4); //不要分两次向管道写入,否则接收方进行判断时会出问题
      write(fd, buf, count);
      // 判断输入是否为end
      if (count == 4 && strncmp(buf, "end", 3) == 0)
      {
        printf("程序结束\n");
        sleep(1);
        close(fd); // 关闭管道
        write(fds[1], "end", 3);
        wait(NULL);
        exit(0);
      }
    }
  }
  else if (pid == 0) // 子进程
  {
    int fd2 = open("./pipeline_file1", O_RDONLY);
    if (fd2 < 0)
    {
      perror("管道文件打开失败");
      exit(-1);
    }
    fcntl(fd2, F_SETFL, O_NONBLOCK);

    char buf[1024];
    while (1)
    {
      read(fds[0], buf, sizeof(buf));
      if (strstr(buf, "end") != NULL)
      {
        close(fd2);
        exit(0);
      }

      int count = read(fd2, buf, sizeof(buf)); // 从管道读数据,并写到标准输出
      write(1, buf, count);
      // 判断读的数据是否为jack:end
      if (count == 4 && strncmp(buf, "end", 3) == 0)
      {
        printf("对方程序结束\n");
        sleep(1);
        write(fds[1], "end", 3);
        close(fd2); // 关闭管道
        exit(0);
      }
    }
  }
  else
  {
    perror("进程创建失败");
  }
  return 0;
}